package com.hgy.plugin.security.realm;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

import com.hgy.common.utils.CollectionUtil;
import com.hgy.plugin.security.SecurityConstant;
import com.hgy.plugin.security.SmartSecurity;
import com.hgy.plugin.security.password.Md5CredentialsMatcher;

/**
 * 基于 Smart 的自定义 Realm (需要实现 SmartSecurity 接口)
 * 
 * @author alone
 *
 */
public class SmartCustomRealm extends AuthorizingRealm{
	
	private final SmartSecurity smartSecurity;
	
	// 初始化 smartSecurity
	public SmartCustomRealm(SmartSecurity smartSecurity) {
		this.smartSecurity = smartSecurity;
		super.setName(SecurityConstant.REALMS_CUSTOM);
		super.setCredentialsMatcher(new Md5CredentialsMatcher());
	}
	
	/**
	 * 认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 
			throws AuthenticationException {
		
		if(token == null){
			throw new AuthenticationException("paramter token is null");
		}
		// 获取表单提交的 username
		String username = ((UsernamePasswordToken)token).getUsername();
		// 根据用户名从数据库中获取密码
		String password = smartSecurity.getPassword(username);
		
		// 将用户名和密码放入 authenticationInfo 对象中. 用于后续认证
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo();
		PrincipalCollection principals = new SimplePrincipalCollection(username, super.getName());
		authenticationInfo.setPrincipals(principals);
		authenticationInfo.setCredentials(password);
		return authenticationInfo;
	}
	
	/**
	 * 授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		
		if(principals == null){
			throw new AuthorizationException("paramter principals is null");
		}
		// 获取已经认证用户的用户名
		String username = (String) super.getAvailablePrincipal(principals);
		
		Set<String> roleNameSet = smartSecurity.getRoleNameSet(username);
		Set<String> permissionNameSet = new HashSet<String>();
		if(CollectionUtil.isNotEmpty(roleNameSet) && roleNameSet.size() > 0){
			for (String roleName : roleNameSet) {
				Set<String> currentPermissionNameSet = smartSecurity.getPermissionNameSet(roleName);
				permissionNameSet.addAll(currentPermissionNameSet);
			}
		}
		// 将用户名和密码放入 authorizationInfo 对象中. 用于后续授权
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.setRoles(roleNameSet);
		authorizationInfo.setStringPermissions(permissionNameSet);
		return authorizationInfo;
	}

	

}
